package com.zxy.study.ui.widget;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.os.Build;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import com.zxy.study.R;


/*
 *  @项目名：  study
 *  @包名：    com.zxy.study.ui.widget
 *  @文件名:   FlipboardView
 *  @创建者:   zhangxy
 *  @创建时间:  2020/1/9 9:59
 *  @描述：    TODO
 */
public class FlipboardView extends View {

	private Bitmap mBitmap;
	private Camera mCamera;
	private int degree;
	private Paint mPaint;
	private Point startPoint = new Point();
	private Point centerPoint = new Point();
	private Path mPath = new Path();

	private ObjectAnimator degreeAnimator;


	public FlipboardView(Context context) {
		this(context, null);
	}

	public FlipboardView(Context context, @Nullable AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public FlipboardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init();
	}

	@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
	public FlipboardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		init();
	}

	private void init() {
		mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
		Bitmap newBitmap = Bitmap.createScaledBitmap(mBitmap, mBitmap.getWidth() * 3, mBitmap.getHeight() * 3, false);
		mBitmap.recycle();
		mBitmap = newBitmap;

		mPaint = new Paint();
		mCamera = new Camera();
		DisplayMetrics metrics = getResources().getDisplayMetrics();
		float newZ = -metrics.density * 6;
		mCamera.setLocation(0, 0, newZ);

		degreeAnimator = ObjectAnimator.ofInt(this, "degree", 0, 360);
		degreeAnimator.setDuration(3000);
		degreeAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
		degreeAnimator.setRepeatCount(ValueAnimator.INFINITE);
	}

	@SuppressWarnings("unused")
	public void setDegree(int degree) {
		this.degree = degree;
		invalidate();
	}

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		degreeAnimator.start();
	}

	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		degreeAnimator.end();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int wMode = MeasureSpec.getMode(widthMeasureSpec);
		if (wMode == MeasureSpec.EXACTLY) {
			int width = MeasureSpec.getSize(widthMeasureSpec);
			startPoint.x = (width - mBitmap.getWidth()) / 2;
		} else {
			widthMeasureSpec = MeasureSpec.makeMeasureSpec(mBitmap.getWidth(), MeasureSpec.EXACTLY);
			startPoint.x = 0;
		}

		int hMode = MeasureSpec.getMode(heightMeasureSpec);
		if (hMode == MeasureSpec.EXACTLY) {
			int height = MeasureSpec.getSize(heightMeasureSpec);
			startPoint.y = (height - mBitmap.getHeight()) / 2;

		} else {
			heightMeasureSpec = MeasureSpec.makeMeasureSpec(mBitmap.getHeight(), MeasureSpec.EXACTLY);
			startPoint.y = 0;
		}
		centerPoint.x = startPoint.x + mBitmap.getWidth() / 2;
		centerPoint.y = startPoint.y + mBitmap.getHeight() / 2;

		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	@RequiresApi(api = Build.VERSION_CODES.O)
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		int rotate = degree > 45 ? 45 : degree;

		double newX;
		double newY;

		mPath.reset();
		if (degree >= 270) {
			newX = centerPoint.x + (centerPoint.y * Math.tan(Math.toRadians(degree - 270)));
			if (newX > getWidth()) {
				newX = getWidth();
				newY = centerPoint.y + centerPoint.x * Math.tan(Math.toRadians(360 - degree));
			} else {
				newY = getHeight();
			}
		} else if (degree >= 180) {
			newY = centerPoint.y + Math.tan(Math.toRadians(degree - 180)) * centerPoint.x;
			if (newY > getHeight()) {
				newX = centerPoint.x - Math.tan(Math.toRadians(270 - degree)) * centerPoint.y;
				newY = getHeight();
			} else {
				newX = 0;
			}
		} else if (degree >= 90) {
			newX = centerPoint.x - (centerPoint.y * Math.tan(Math.toRadians(degree - 90)));
			if (newX < 0) {
				newX = 0;
				newY = centerPoint.y - centerPoint.x * Math.tan(Math.toRadians(180 - degree));
			} else {
				newY = 0;
			}
		} else {
			newX = centerPoint.x;
			newY = 0;
		}

		mPath.moveTo((float) newX, (float) newY);
		if (newY == 0) {
			mPath.lineTo(0, 0);
			mPath.lineTo(0, getHeight());
		} else if (newY == getHeight()) {
			mPath.lineTo(getWidth(), getHeight());
			mPath.lineTo(getWidth(), 0);
		} else {
			if (newX == 0) {
				mPath.lineTo(0, getHeight());
				mPath.lineTo(getWidth(), getHeight());
			} else {
				mPath.lineTo(getWidth(), 0);
				mPath.lineTo(0, 0);
			}
		}

		mPath.lineTo((float) (getWidth() - newX), (float) (getHeight() - newY));
		mPath.close();

		//绘制第一部分
		canvas.save();
		canvas.clipPath(mPath);
		canvas.drawBitmap(mBitmap, startPoint.x, startPoint.y, mPaint);
		canvas.restore();

		//绘制第二部分
		canvas.save();
		canvas.clipOutPath(mPath);

		mCamera.save();
		int rotateCanvas = degree > 90 ? degree - 90 : 0;
		mCamera.rotateY(-rotate);
//		Matrix matrix = new Matrix();
//		mCamera.getMatrix(matrix);
//		matrix.postTranslate(centerPoint.x, centerPoint.y);
//		matrix.setRotate(-rotateCanvas);
//		canvas.setMatrix(matrix);
		canvas.translate(centerPoint.x, centerPoint.y);
		canvas.rotate(-rotateCanvas);
		mCamera.applyToCanvas(canvas);
		canvas.rotate(rotateCanvas);
		canvas.translate(-centerPoint.x, -centerPoint.y);
		mCamera.restore();

		canvas.drawBitmap(mBitmap, startPoint.x, startPoint.y, mPaint);

		canvas.restore();
	}
}
